package com.pro.common.file.storage.huawei.util;/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
 */

import com.obs.services.ObsClient;
import com.obs.services.ObsConfiguration;
import com.obs.services.exception.ObsException;
import com.obs.services.model.HttpMethodEnum;
import com.obs.services.model.TemporarySignatureRequest;
import com.obs.services.model.TemporarySignatureResponse;

import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class PutObjectWithCallback_TempUrl {
    public static void main(String[] args) {
        // 您可以通过环境变量获取访问密钥AK/SK，也可以使用其他外部引入方式传入。如果使用硬编码可能会存在泄露风险。
        // 您可以登录访问管理控制台获取访问密钥AK/SK
        String ak = System.getenv("ACCESS_KEY_ID");
        String sk = System.getenv("SECRET_ACCESS_KEY_ID");
        // 【可选】如果使用临时AK/SK和SecurityToken访问OBS，同样建议您尽量避免使用硬编码，以降低信息泄露风险。
        // 您可以通过环境变量获取访问密钥AK/SK/SecurityToken，也可以使用其他外部引入方式传入。
        String securityToken = System.getenv("SECURITY_TOKEN");

        // endpoint填写桶所在的endpoint, 此处以华北-北京四为例，其他地区请按实际情况填写。
        // 您可以通过环境变量获取endPoint，也可以使用其他外部引入方式传入。
        String endPoint = System.getenv("ENDPOINT_S");
        //        String endPoint = "https://obs.cn-north-4.myhuaweicloud.com";
        ObsConfiguration config = new ObsConfiguration();

        config.setEndPoint(endPoint);
        // 创建ObsClient实例
        ObsClient obsClient = new ObsClient(ak, sk, securityToken, config);
        try {
            // 示例桶名
            String exampleBucket = "test-bucket-name";
            String exampleObjectName = "object_name";
            // URL有效期，3600秒
            long expireSeconds = 3600L;
            Map<String, String> headers = new HashMap<>();
            String contentType = "text/plain";
            headers.put("Content-Type", contentType);
            TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.PUT, expireSeconds);
            request.setBucketName(exampleBucket);
            request.setObjectKey(exampleObjectName);
            request.setHeaders(headers);
            Map<String, Object> params = new HashMap<>();
            params.put("x-obs-callback", "eyJjYWxsYmFja1VybCI6Imh0dHBzOi8vc3N6LnJoZG9hLmNuL3Nzby9maWxlVXBsb2FkQ2hhbmdlIiwiY2FsbGJhY2tCb2R5IjoiYnVja2V0PSQoYnVja2V0KSZrZXk9JChrZXkpJmV0YWc9JChldGFnKSJ9");
            request.setQueryParams(params);
            TemporarySignatureResponse response = obsClient.createTemporarySignature(request);
            System.out.println("Creating object using temporary signature url:");
            System.out.println("\t" + response.getSignedUrl());
            Request.Builder builder = new Request.Builder();
            for (Map.Entry<String, String> entry : response.getActualSignedRequestHeaders().entrySet()) {
                builder.header(entry.getKey(), entry.getValue());
            }
            // 使用PUT请求生成的临时url，上传对象
            Request httpRequest =
                builder.url(response.getSignedUrl())
                    .put(RequestBody.create(MediaType.parse(contentType), "Hello OBS".getBytes("UTF-8")))
                    .build();
            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
            sslContext.init(null, new TrustManager[]{trustAllManager}, new SecureRandom());
            OkHttpClient httpClient =
                new OkHttpClient.Builder()
                    .followRedirects(false)
                    .retryOnConnectionFailure(false)
                    .cache(null)
                    .sslSocketFactory(sslContext.getSocketFactory(), trustAllManager)
                    .build();
            Call c = httpClient.newCall(httpRequest);
            Response res = c.execute();
            System.out.println("Status:" + res.code());
            System.out.println("Headers:" + res.headers());
            if (res.body() != null) {
                System.out.println("Content:" + res.body().string() + "\n");
            }
            res.close();
            System.out.println("PutObject successfully");
        } catch (ObsException e) {
            System.out.println("PutObjectWithCallback failed");
            // 请求失败,打印http状态码
            System.out.println("HTTP Code:" + e.getResponseCode());
            // 请求失败,打印服务端错误码
            System.out.println("Error Code:" + e.getErrorCode());
            // 请求失败,打印详细错误信息
            System.out.println("Error Message:" + e.getErrorMessage());
            // 请求失败,打印请求id
            System.out.println("Request ID:" + e.getErrorRequestId());
            System.out.println("Host ID:" + e.getErrorHostId());
            Map<String, String> headers = e.getResponseHeaders();
            // 遍历Map的entry,打印所有报错相关头域
            if(headers != null){
                for (Map.Entry<String, String> header : headers.entrySet()) {
                    if(header.getKey().contains("error")){
                        System.out.println(header.getKey()+":"+header.getValue());
                    }
                }
            }
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("PutObjectWithCallback failed");
            // 其他异常信息打印
            e.printStackTrace();
        }
    }
    static X509TrustManager trustAllManager = new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            // 客户端证书验证
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
        {
            // 服务端证书验证
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    };
}
